package com.ybwh.springboot2.sharding4.ext.sharding;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Range;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;


/**
 * 以月份进行分表策略
 *
 * PreciseShardingAlgorithm:用于处理使用单一键作为分片键的=与IN进行分片的场景,需要配合StandardShardingStrategy使用。
 * RangeShardingAlgorithm:范围分片算法,用于处理使用单一键作为分片键的BETWEEN AND进行分片的场景,需要配合StandardShardingStrategy使用。
 *
 */
@Slf4j
public class DateStandardShardingAlgorithm implements PreciseShardingAlgorithm<Date> , RangeShardingAlgorithm<Date> {
	private static final DateFormat YYYY_MM = new SimpleDateFormat("yyyyMM");

	@Override
	public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Date> shardingValue) {
		log.info("-------------availableTargetNames={},shardingValue={}", JSON.toJSONString(availableTargetNames),shardingValue);

		return shardingValue.getLogicTableName() + YYYY_MM.format(shardingValue.getValue());
	}

	@Override
	public Collection<String> doSharding(Collection<String> availableTargetNames,
			RangeShardingValue<Date> shardingValue) {

		log.info("-------------availableTargetNames={},shardingValue={}", JSON.toJSONString(availableTargetNames),shardingValue);
		
		Collection<String> result = new HashSet<>();
		Range<Date> ranges = shardingValue.getValueRange();
		Date startTime = ranges.lowerEndpoint();
		Date endTime = ranges.upperEndpoint();
		// 此处应该返回 tablePrefix+201808 , tablePrefix+201809,tablePrefix+201810,
		Calendar cal = Calendar.getInstance();
		
		
		final String logicTableName = shardingValue.getLogicTableName();

		while (startTime.getTime() <= endTime.getTime()) {
			result.add(logicTableName + YYYY_MM.format(startTime));
			cal.setTime(startTime);// 设置起时间
			cal.add(Calendar.MONTH, 1);
			startTime = cal.getTime();
		}
		return result;
	}
}
